package com.yxh.controller;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wordnik.swagger.annotations.ApiImplicitParam;
import com.wordnik.swagger.annotations.ApiImplicitParams;

import com.yxh.common.annotation.Authorization;
import com.yxh.pojo.*;
import com.yxh.service.*;
import com.yxh.util.*;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;

import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.impl.identity.Authentication;


import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;

import static com.alibaba.druid.support.json.JSONUtils.toJSONString;
import static com.yxh.util.APIErrorCode.SUCCESS;


/**
 * Created by asus on 2018/6/2.
 */
@Scope("prototype")
@RestController
@RequestMapping(value = "/flow")
public class FlowController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(FlowController.class);
    private Response response;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private MakingsService makingsService;

    @Autowired
    private ChangeService changeService;

    @Autowired
    private HideService hideService;

    @Autowired
    private ViciousService viciousService;

    @Autowired
    private PositionService positionService;




    @GetMapping("/task/{id}")
    @Authorization
    @ApiImplicitParams({
            @ApiImplicitParam(name = "authorization", value = "authorization", required = true, dataType = "string", paramType = "header"),
    })
    public Response list(@RequestParam(required = false, defaultValue = "1", name = "page") int page,
                         @RequestParam(required = false, defaultValue = "10", name = "pageSize") int pageSize,
                         @RequestParam(required = false,name = "code") String  code,
                         @PathVariable(value = "id") String id) throws Exception {

        try {
            PageBean pageBean = new PageBean();
            pageBean.setPage(page);
            pageBean.setPageSize(pageSize);

            List<Task> taskList = null;
            long total;
            if(StringUtil.isNotEmpty(code)){
                taskList = taskService.createTaskQuery().taskCandidateUser(id).
                        processVariableValueLikeIgnoreCase("code","%" + code + "%").orderByTaskCreateTime().desc().
                        listPage(pageBean.getStart(), pageBean.getPageSize());
                total = taskService.createTaskQuery().taskCandidateUser(id).processVariableValueLikeIgnoreCase("code","%" + code + "%").count();

            }
            else{
                /*//查询当前流程的任务
                taskList = taskService.createTaskQuery().taskCandidateUser(id).orderByTaskCreateTime().desc().taskCandidateUser(id).
                        listPage(pageBean.getStart(), pageBean.getPageSize());
                //对数据进行转换
                total = taskService.createTaskQuery().taskCandidateUser(id).count();*/
               //拼接  代办列表
                PageInfo pageInfo =positionService.getAuditListApp(id,page,pageSize);
                response = Response.returnResponse(SUCCESS);
                response.setData(pageInfo);
                return response;


            }

          /*  List<Task> taskList = taskService.createTaskQuery().taskAssignee(id).list();*/
            List<MyTask> tasks = new ArrayList<MyTask>();

            for (Task task : taskList) {

                MyTask t = new MyTask();

                t.setId(task.getId());
                t.setName(task.getName());
                t.setCreateTime(task.getCreateTime());
                Map<String,Object> m=null;
                String process=task.getProcessDefinitionId();
               if(process.contains(TaskCode.MAKE_KEY.getDesc())){
                    m=makingsService.getById((String) taskService.getVariable(task.getId(), "makingsId"));
                   t.setKey(TaskCode.MAKE_KEY.getDesc());
               }
                else if(process.contains(TaskCode.CHANGE_KEY.getDesc())){
                    m=changeService.getNewById((String) taskService.getVariable(task.getId(), "changeId"));
                    t.setKey(TaskCode.CHANGE_KEY.getDesc());
                }
                else if(process.contains(TaskCode.HIDE_KEY.getDesc())){
                    m=hideService.getNewById((String) taskService.getVariable(task.getId(), "hideId"));
                    t.setKey(TaskCode.HIDE_KEY.getDesc());
                }
                else if(process.contains(TaskCode.FAULT_KEY.getDesc())){
                    m=viciousService.get1((String) taskService.getVariable(task.getId(), "viciousId"));
                    t.setKey(TaskCode.FAULT_KEY.getDesc());
                }
                else if(process.contains(TaskCode.SUPER_KEY.getDesc())){
                    m=viciousService.get1((String) taskService.getVariable(task.getId(), "viciousId"));
                    t.setKey(TaskCode.SUPER_KEY.getDesc());
                }


                t.setModel(m==null?new JSONObject():m);
                tasks.add(t);
            }

            response= Response.returnResponse(APIErrorCode.SUCCESS);
            response.setData(pageInfo(page,pageSize,total,tasks));
        } catch (Exception e) {
            e.printStackTrace();
            response = Response.returnResponse(APIErrorCode.SELECT_ERROR);
        }


        return response;
    }

    @PostMapping("/audit")
   @Authorization
    @ApiImplicitParams({
            @ApiImplicitParam(name = "authorization", value = "authorization", required = true, dataType = "string", paramType = "header"),
    })
    public Response audit(@RequestBody TaskParam param) throws Exception {

        Map<String, Object> variables = new HashMap<String, Object>();
        String taskId=param.getTaskId(),userId=param.getUserId(),comment=param.getComment(),viciousId= (String) taskService.getVariable(taskId, "viciousId"),
                positionId=(String) taskService.getVariable(taskId, "positionId"),
                unitId=param.getUnitId(),nextId=param.getNextId(),url=param.getUrl();
        int  state=param.getState();

        History h=new History(); //存历史记录
        h.setUserid(userId);
        h.setViciousId(viciousId);
        h.setComment(comment);
        String megs="",operation;
        //修改到岗到位状态
        if(StringUtil.isNotEmpty(positionId)){
            Position p =new Position();
            p.setPositionId(positionId);
            if(state == TaskCode.STATE_1.getValue()){
                p.setState(TaskCode.STATE_MEG4.getDesc());
            }
            else if(state == TaskCode.STATE_2.getValue())
                p.setState(TaskCode.STATE_MEG7.getDesc());
            else
                p.setState(TaskCode.STATE_MEG8.getDesc());
             positionService.update(p);

        }

        variables.put("meg", state);

        Vicious s=new Vicious();
        s.setViciousId(viciousId);
        if (state == TaskCode.STATE_1.getValue()) {
            megs=TaskCode.STATE_MEG9.getDesc();
            h.setState(TaskCode.STATE_MEG1.getDesc());
            s.setStatu(TaskCode.STATE_MEG4.getDesc());
        } else if (state == TaskCode.STATE_2.getValue()) {
           // 有缺陷进行处理 更新缺陷表  状态
            s.setStatu(TaskCode.STATE_MEG5.getDesc());
            h.setState(TaskCode.STATE_MEG2.getDesc());
            h.setUnitId(unitId);
            h.setPresideId(nextId);
            h.setDate(param.getDate());
            megs=TaskCode.STATE_MEG10.getDesc();
        }
      if(StringUtil.isNotEmpty(nextId)){
          variables.put("user1", nextId);
      }

        if(state==TaskCode.STATE_0.getValue()){
            megs=TaskCode.STATE_MEG11.getDesc();
            operation=TaskCode.STATE_MEG13.getDesc();
            s.setStatu(TaskCode.STATE_MEG6.getDesc());
            h.setState(TaskCode.STATE_MEG3.getDesc());
            if(StringUtil.isNotEmpty(url)){
                String id=SnowflakeIdWorker.creatId();
                h.setImgId(id);
                String [] img=url.split(",");
                Map<String,Object> parm=new HashMap<String,Object>();
                parm.put("foreign_id",id);
                for (String anImg : img) {
                    parm.put("img_id", SnowflakeIdWorker.creatId());
                    parm.put("url", anImg);
                    viciousService.insertImg(parm);
                }
            }

        }
        else
        {
            operation=TaskCode.STATE_MEG12.getDesc();
        }

        h.setOperationName(operation);
        viciousService.update(s);//修改状态
        viciousService.insertHistroy(h);//记录每次操作流程提供的数据



        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        String processInstacnId = task.getProcessInstanceId();
        Authentication.setAuthenticatedUserId(operation);
        taskService.addComment(taskId, processInstacnId, megs);

        taskService.complete(taskId,variables);

        return  response= Response.returnResponse(APIErrorCode.SUCCESS);
    }

    /**
     * ��ѯ��ǰ����ͼ
     *
     * @param taskId
     * @param response
     * @throws Exception
     */
    @RequestMapping("/show/{taskId}")
    public ModelAndView showCurrentView(@PathVariable(value = "taskId")String taskId,
                                        HttpServletResponse response) throws Exception {


        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        String processDefinitionId = task.getProcessDefinitionId();

        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();

        InputStream in = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getDiagramResourceName());
        OutputStream out = response.getOutputStream();
        int len;
        byte[] bytes = new byte[1024];
        while ((len = in.read(bytes)) != -1) {
            out.write(bytes, 0, len);
        }
        out.close();
        in.close();
        return null;
    }

    @GetMapping("/history/{taskId}")
    @Authorization
    @ApiImplicitParams({
            @ApiImplicitParam(name = "authorization", value = "authorization", required = true, dataType = "string", paramType = "header"),
    })
    public Response listHistoryComment(@PathVariable(value = "taskId")String taskId)throws Exception {
        if (taskId == null) {
            return null;
        }
        HistoricTaskInstance historicTaskInstance =historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
        String processInstanceId =historicTaskInstance.getProcessInstanceId();
        List<Comment> comments = taskService.getProcessInstanceComments(processInstanceId);
       List<Map<String,Object>> li =new ArrayList<Map<String,Object>>();
        for(Comment c:comments){
           Map<String,Object> map=new HashMap<String,Object>();
            map.put("time",DateUtils.formatDate(c.getTime(),"yyyy-MM-dd HH:mm:ss"));
            map.put("userId",c.getUserId());
            map.put("message",c.getFullMessage());
            li.add(map);
        }

        response= Response.returnResponse(APIErrorCode.SUCCESS);
        response.setData(li);
        return response;
    }

    @GetMapping("/history/list/{taskId}")
    @Authorization
    @ApiImplicitParams({
            @ApiImplicitParam(name = "authorization", value = "authorization", required = true, dataType = "string", paramType = "header"),
    })
    public Response listHistory(@PathVariable(value = "taskId")String taskId)throws Exception {
        if (taskId == null) {
            return null;
        }
      //根基流程定义查询历史节点处理信息
        List<Comment> comments = taskService.getProcessInstanceComments(taskId);
        List<Map<String,Object>> li =new ArrayList<Map<String,Object>>();
        for(Comment c:comments){
            Map<String,Object> map=new HashMap<String,Object>();
            map.put("time",DateUtils.formatDate(c.getTime(),"yyyy-MM-dd HH:mm:ss"));
            map.put("userId",c.getUserId());
            map.put("message",c.getFullMessage());
            li.add(map);
        }

        response= Response.returnResponse(APIErrorCode.SUCCESS);
        response.setData(li);
        return response;
    }

    @GetMapping("/history/list")
    @Authorization
    @ApiImplicitParams({
            @ApiImplicitParam(name = "authorization", value = "authorization", required = true, dataType = "string", paramType = "header"),
    })
    public Response history(@RequestParam(required = false, defaultValue = "1", name = "page") int page,
                         @RequestParam(required = false, defaultValue = "10", name = "pageSize") int pageSize,
                         @RequestParam(required = false, name = "key") String key,
                            @RequestParam(required = false, name = "code") String code) throws Exception {

        try {
            if(key.contains("work")){
                PageInfo pageInfo = positionService.getListApp(code, page, pageSize);
                response = Response.returnResponse(SUCCESS);
                response.setData(pageInfo);
                return response;
            }

            PageBean pageBean = new PageBean();
            pageBean.setPage(page);
            pageBean.setPageSize(pageSize);


            //根据流程定义key 和对应的设计变更编码等查询所有任务
            long total;
            List<HistoricTaskInstance> historicTaskInstances;
           if(StringUtil.isNotEmpty(code)) {
                historicTaskInstances= historyService.createHistoricTaskInstanceQuery().processDefinitionKeyLike("%"+key+"%").processVariableValueLikeIgnoreCase("code","%" + code + "%").orderByTaskCreateTime().desc()
                        .listPage(pageBean.getStart(), pageBean.getPageSize());
                total =  historyService.createHistoricTaskInstanceQuery().processDefinitionKeyLike("%"+key+"%").processVariableValueLikeIgnoreCase("code","%" + code + "%").count();

            }
            else{
              historicTaskInstances= historyService.createHistoricTaskInstanceQuery().processDefinitionKeyLike("%"+key+"%").orderByTaskCreateTime().desc()
                      .listPage(pageBean.getStart(), pageBean.getPageSize());
              total =  historyService.createHistoricTaskInstanceQuery().processDefinitionKeyLike("%"+key+"%").count();

          }
            List<MyTask> tasks = new ArrayList<MyTask>();
           for(HistoricTaskInstance h:historicTaskInstances){

             MyTask t = new MyTask();
             String process=h.getProcessDefinitionId(), processInstanceId=h.getProcessInstanceId();
             t.setId(processInstanceId);
             t.setName(h.getName());
             t.setCreateTime(h.getCreateTime());
             Map<String,Object> m=null;
             if(process.contains(TaskCode.MAKE_KEY.getDesc())){
                 m=makingsService.getById(value("makingsId",processInstanceId));
                 t.setKey(TaskCode.MAKE_KEY.getDesc());
             }
             else if(process.contains(TaskCode.CHANGE_KEY.getDesc())){
                 m=changeService.getNewById(value("changeId",processInstanceId));
                 t.setKey(TaskCode.CHANGE_KEY.getDesc());
             }
             else if(process.contains(TaskCode.HIDE_KEY.getDesc())){
                 m=hideService.getNewById(value("hideId",processInstanceId));
                 t.setKey(TaskCode.HIDE_KEY.getDesc());
             }
             else if(process.contains(TaskCode.FAULT_KEY.getDesc())){
                 m=viciousService.get1(value("viciousId",processInstanceId));
                 t.setKey(TaskCode.FAULT_KEY.getDesc());
             }
             else if(process.contains(TaskCode.SUPER_KEY.getDesc())){
                 m=viciousService.get1(value("viciousId",processInstanceId));
                 t.setKey(TaskCode.SUPER_KEY.getDesc());
             }
               t.setModel(m==null?new JSONObject():m);
               tasks.add(t);
         }
            response= Response.returnResponse(APIErrorCode.SUCCESS);
            response.setData(pageInfo(page,pageSize,total,tasks));
        } catch (Exception e) {
            e.printStackTrace();
            response = Response.returnResponse(APIErrorCode.SELECT_ERROR);
        }

        return response;
    }

    public String value(String value,String processInstanceId){
        /**根据流程查询历史的流程变量*/
        List<HistoricVariableInstance> list = historyService
                .createHistoricVariableInstanceQuery()//创建一个历史的流程变量查询
                .variableName(value).processInstanceId(processInstanceId).
                        list();
        return list.get(0).getValue().toString();

    }

    public PageInfo pageInfo(int page,int pageSize,long total, List<MyTask> tasks){
        JsonConfig jsonConfig = new JsonConfig();
        jsonConfig.registerJsonValueProcessor(java.util.Date.class, new DateJsonValueProcessor("yyyy-MM-dd HH:mm:ss"));
        JSONObject result = new JSONObject();
        JSONArray jsonArray = JSONArray.fromObject(tasks, jsonConfig);
        long pages;
        if(total%pageSize==0){
             pages=total/pageSize ;
        }
        else  pages=total/pageSize+1 ;
        PageInfo pageInfo = new PageInfo();
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pageSize);
        pageInfo.setList(jsonArray);
        pageInfo.setPages((int)pages);
        pageInfo.setTotal((int) total);
        pageInfo.setNextPage(page+1);
        pageInfo.setPrePage(page-1);
        pageInfo.setSize(tasks.size());
        pageInfo.setLastPage((int)pages);
        pageInfo.setIsFirstPage(page == 1);
        pageInfo.setIsLastPage(page == (int) pages);
        pageInfo.setHasNextPage(page!=(int) pages);
        pageInfo.setHasPreviousPage(page!=1);
        return pageInfo;
    }

}
